package com.meme.io.editor;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.meme.editor.model.sprite2d.*;
import com.meme.util.FileUtil;
import com.meme.util.XmlUtil;

import java.util.LinkedList;
import java.util.List;

public class PlayfieldXmlFileLoader 
{
	static Logger logger = Logger.getLogger (PlayfieldXmlFileLoader.class);
	
	String mPlayfieldXmlFilename;
	

	public Sprite2dFile loadFromXmlDocument (Document document, String filename)
	{
		mPlayfieldXmlFilename = filename;
		
		Sprite2dFile sprite2dFile = new Sprite2dFile ();
		
		loadPlayfieldXmlFile (document, sprite2dFile);

		sprite2dFile.setHostFilename (filename);

		return sprite2dFile;
	}
	
//--------------------------------------------------------------------
	
	void loadPlayfieldXmlFile (Document document, Sprite2dFile sprite2dFile)
	{
		Element mapElement = XmlUtil.getChildElementByName (document, "Map");
		
		Tiled2dBackground background = sprite2dFile.createNewTiledBackground();
		int map_width = XmlUtil.parseAttributeAsInt(mapElement, "height");
		int map_height = XmlUtil.parseAttributeAsInt(mapElement, "width");
		
		// layers
		{
			Element[] layerElements = XmlUtil.getChildElementsByName(mapElement, "Layer");
			Element[] visualLayerElements = XmlUtil.getChildElementsByName(mapElement, "VisualLayer");
			Element[] physicalLayerElements = XmlUtil.getChildElementsByName(mapElement, "PhysicalLayer");
			
			List<Element> layerElementList = new LinkedList<Element> ();
			for (Element layerElement : layerElements)
				layerElementList.add (layerElement);
			for (Element layerElement : visualLayerElements)
				layerElementList.add (layerElement);
			for (Element layerElement : physicalLayerElements)
				layerElementList.add (layerElement);
			
			boolean firstLayer = true;
			for (Element layerElement : layerElementList)
			{
				//
				int cell_width  = XmlUtil.parseAttributeAsInt(layerElement, "tilew"); 
				int cell_height = XmlUtil.parseAttributeAsInt(layerElement, "tileh"); 
				int cell_rows   = XmlUtil.parseAttributeAsInt(layerElement, "tileh_t"); 
				int cell_cols   = XmlUtil.parseAttributeAsInt(layerElement, "tilew_t"); 
				
				//
				ModuleImage moduleImage = sprite2dFile.createNewModuleImage();

				String imageFilename = FileUtil.getFullPathFilename(
						layerElement.getAttribute("file"), 
						mPlayfieldXmlFilename );
				moduleImage.setImageFilename(imageFilename);
				
				if ( ! moduleImage.isValid() )
				{
					imageFilename = FileUtil.getFullPathFilename(
							FileUtil.getFilename ( layerElement.getAttribute("file") ), 
							mPlayfieldXmlFilename );					
					moduleImage.setImageFilename(imageFilename);
				}
				

				int tilePaletteRows = moduleImage.getHeight() / cell_height;
				int tilePaletteCols = moduleImage.getWidth() / cell_width; 
				
				//
				PureModuleGroup pureModuleGroup = sprite2dFile.createNewPureModuleGroup();
				pureModuleGroup.setModuleImage (moduleImage);
				for (int row = 0; row < tilePaletteRows; ++ row)
				{
					for (int col = 0; col < tilePaletteCols; ++ col)
					{
						PureModule pureModule = pureModuleGroup.createNewModule(col * cell_width, row * cell_height, cell_width, cell_height);
					}
				}
				
				//
				Tiled2dPalette tilePalette = sprite2dFile.createNewTilePalette();
				tilePalette.setCellSize(cell_width, cell_height);
				tilePalette.setGridSize(tilePaletteRows, tilePaletteCols);
				for (int i = 0; i < tilePalette.getChildrenCount(); ++ i)
				{
					Tiled2dModule tile = tilePalette.getTiled2dModuleByIndex(i);
					tile.setModule ( (Module)pureModuleGroup.getChildByIndex(i) );
				}
				
				//
				if (firstLayer)
				{
					firstLayer = false;

					background.removeAllChildren();
					background.setCellSize(cell_width, cell_height);
					background.setGridSize(cell_rows, cell_cols);
				}

				
				// cells
				Tiled2dLayer layer = background.createNewTiled2dLayer();
				
				Element dataElement = XmlUtil.getChildElementByName(layerElement, "Data");
				String cellValuesString = dataElement.getTextContent();
				String[] cellValueStrings = cellValuesString.split(",");
				int index = 0;
				for (int row = 0; row < cell_rows; ++ row)
				{
					for (int col = 0; col < cell_cols; ++ col)
					{
						Tiled2dLayerCell layerCell = layer.getLayerCellByPos (row, col);
						
						int value = Integer.parseInt(cellValueStrings[index ++]);
						if (value >= 0)
						{
							int moduleID = value & 0x9FFFFFFF;
							if ( moduleID >= tilePalette.getChildrenCount() )
								moduleID = 0;
							
							layerCell.setModule(tilePalette.getTiled2dModuleByIndex(moduleID));
							layerCell.setFlipX((value & 0x40000000) != 0);
							layerCell.setFlipY((value & 0x20000000) != 0);
						}
					}
				}
			}
		}
	}
	
}
